/*
* @file    :drv_uart.c
* @module  :UART
* @author  :LingFengLu
* @date    :2023-06-06
*/

#include "drv_uart.h"
#include "drv_gpio.h"
#include "log.h"
#include "rf_driver_ll_usart.h"
#include "rf_driver_ll_lpuart.h"
#include "bluenrg_lp_evb_config.h"
#include <stdint.h>

//Constant definition    宏定义
#define DUG_TX_Channel_PIN                    GPIO_CHANNEL(PORT_A,PIN1)         
#define DUG_RX_Channel_PIN                    GPIO_CHANNEL(PORT_B,PIN0)   


#define GC_TX_Channel_PIN                    GPIO_CHANNEL(PORT_B,PIN15)         
#define GC_RX_Channel_PIN                    GPIO_CHANNEL(PORT_B,PIN14)   


#define GC1_TX_Channel_PIN                    GPIO_CHANNEL(PORT_B,PIN6)         
#define GC1_RX_Channel_PIN                    GPIO_CHANNEL(PORT_B,PIN7) 

typedef struct
{
	USART_TypeDef* usart ;
	uint usart_irq ;
	uint32 baudRate;
	uint32 tx_preiph ;
	uint32 rx_preiph ;
	uint32 GPIO_tx_AF ;
	uint32 GPIO_rx_AF ;
	uint ui_GPIOChannelTX;
	uint ui_GPIOChannelRX;
} drv_uart_profile;



//Private variable definition    私有变量定义
static GPIO_TypeDef*  Port[PORT_COUNT] = {GPIOA ,GPIOB} ;
static uint32 Pin[PIN_COUNT] = {
	LL_GPIO_PIN_0,LL_GPIO_PIN_1,LL_GPIO_PIN_2,LL_GPIO_PIN_3,
	LL_GPIO_PIN_4,LL_GPIO_PIN_5,LL_GPIO_PIN_6,LL_GPIO_PIN_7,
	LL_GPIO_PIN_8,LL_GPIO_PIN_9,LL_GPIO_PIN_10,LL_GPIO_PIN_11,
	LL_GPIO_PIN_12,LL_GPIO_PIN_13,LL_GPIO_PIN_14,LL_GPIO_PIN_15
} ;

static const drv_uart_profile m_t_UARTProfile[DRV_UART_COUNT_DEVICE_ID] = 
{
	{
		USART1 ,
		USART1_IRQn ,
		115200 ,
		LL_AHB_PERIPH_GPIOA ,
		LL_AHB_PERIPH_GPIOB ,
		LL_GPIO_AF_2 ,
		LL_GPIO_AF_0 ,
		DUG_TX_Channel_PIN ,
		DUG_RX_Channel_PIN 
	},
	{
		USART1 ,
		USART1_IRQn ,
		38400 ,
		LL_AHB_PERIPH_GPIOB ,
		LL_AHB_PERIPH_GPIOB ,
		LL_GPIO_AF_6 ,
		LL_GPIO_AF_6 ,
		GC_TX_Channel_PIN ,
		GC_RX_Channel_PIN 
	},
	{
		LPUART1 ,
		LPUART1_IRQn ,
		115200 ,
		LL_AHB_PERIPH_GPIOB ,
		LL_AHB_PERIPH_GPIOB ,
		LL_GPIO_AF_3 ,
		LL_GPIO_AF_3 ,
		GC1_TX_Channel_PIN ,
		GC1_RX_Channel_PIN 
	}
};


//Private function declaration   私有函数申明


//Public function definition   公共函数定义

void DrvUart_Init(uint ui_DeviceID)
{
	uint8 u8_Port_TX = (m_t_UARTProfile[ui_DeviceID].ui_GPIOChannelTX & DRV_GPIO_MASK_PORT) >> 4;
	uint8 u8_Pin_TX = m_t_UARTProfile[ui_DeviceID].ui_GPIOChannelTX & DRV_GPIO_MASK_PIN;
	uint8 u8_Port_RX = (m_t_UARTProfile[ui_DeviceID].ui_GPIOChannelRX & DRV_GPIO_MASK_PORT) >> 4;
	uint8 u8_Pin_RX = m_t_UARTProfile[ui_DeviceID].ui_GPIOChannelRX & DRV_GPIO_MASK_PIN;
	
	/* Initialize the GPIOs associated to the UART port */
	LL_AHB_EnableClock(m_t_UARTProfile[ui_DeviceID].tx_preiph) ;
	LL_GPIO_SetPinMode(Port[u8_Port_TX], Pin[u8_Pin_TX], LL_GPIO_MODE_ALTERNATE);
	LL_GPIO_SetPinSpeed(Port[u8_Port_TX], Pin[u8_Pin_TX], LL_GPIO_SPEED_FREQ_HIGH);
	LL_GPIO_SetPinOutputType(Port[u8_Port_TX], Pin[u8_Pin_TX], LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinPull(Port[u8_Port_TX], Pin[u8_Pin_TX], LL_GPIO_PULL_NO);
	if(ui_DeviceID == DRV_UART_DEVICE_ID_1||(ui_DeviceID == DRV_UART_DEVICE_ID_3))
	{
		LL_GPIO_SetAFPin_0_7(Port[u8_Port_TX], Pin[u8_Pin_TX], m_t_UARTProfile[ui_DeviceID].GPIO_tx_AF);
	}
	else
	{
		LL_GPIO_SetAFPin_8_15(Port[u8_Port_TX], Pin[u8_Pin_TX], m_t_UARTProfile[ui_DeviceID].GPIO_tx_AF) ;
	}
	
	LL_AHB_EnableClock(m_t_UARTProfile[ui_DeviceID].rx_preiph) ;
	LL_GPIO_SetPinMode(Port[u8_Port_RX], Pin[u8_Pin_RX], LL_GPIO_MODE_ALTERNATE);
	LL_GPIO_SetPinSpeed(Port[u8_Port_RX], Pin[u8_Pin_RX], LL_GPIO_SPEED_FREQ_HIGH);
	LL_GPIO_SetPinOutputType(Port[u8_Port_RX], Pin[u8_Pin_RX], LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinPull(Port[u8_Port_RX], Pin[u8_Pin_RX], LL_GPIO_PULL_NO);
	if(ui_DeviceID == DRV_UART_DEVICE_ID_1||(ui_DeviceID == DRV_UART_DEVICE_ID_3))
	{
		LL_GPIO_SetAFPin_0_7(Port[u8_Port_RX], Pin[u8_Pin_RX], m_t_UARTProfile[ui_DeviceID].GPIO_rx_AF);
	}
	else
	{
		LL_GPIO_SetAFPin_8_15(Port[u8_Port_RX], Pin[u8_Pin_RX], m_t_UARTProfile[ui_DeviceID].GPIO_rx_AF) ;
	}
	
	if(ui_DeviceID == DRV_UART_DEVICE_ID_1 || (ui_DeviceID == DRV_UART_DEVICE_ID_2))
	{
		LL_APB1_EnableClock(LL_APB1_PERIPH_USART) ;
		/* UART parameter configuration*/
		LL_USART_SetBaudRate(m_t_UARTProfile[ui_DeviceID].usart, LL_USART_PRESCALER_DIV1, LL_USART_OVERSAMPLING_16, m_t_UARTProfile[ui_DeviceID].baudRate);
		LL_USART_ConfigCharacter(m_t_UARTProfile[ui_DeviceID].usart, LL_USART_DATAWIDTH_8B, LL_USART_PARITY_NONE, LL_USART_STOPBITS_1);
		LL_USART_SetTransferDirection(m_t_UARTProfile[ui_DeviceID].usart, LL_USART_DIRECTION_TX_RX);
		LL_USART_SetHWFlowCtrl(m_t_UARTProfile[ui_DeviceID].usart, LL_USART_HWCONTROL_NONE);
		
		LL_USART_SetRXFIFOThreshold(m_t_UARTProfile[ui_DeviceID].usart, LL_USART_FIFOTHRESHOLD_1_8);
		LL_USART_SetTXFIFOThreshold(m_t_UARTProfile[ui_DeviceID].usart, LL_USART_FIFOTHRESHOLD_1_8);
		LL_USART_EnableFIFO(m_t_UARTProfile[ui_DeviceID].usart);
		
		LL_USART_ConfigAsyncMode(m_t_UARTProfile[ui_DeviceID].usart);
		
		/* Enable the UART */
		LL_USART_Enable(m_t_UARTProfile[ui_DeviceID].usart);
		/* Enable the RX not empty interrupt */
		LL_USART_EnableIT_RXNE(m_t_UARTProfile[ui_DeviceID].usart);
	}
	else
	{
		LL_APB1_EnableClock(LL_APB1_PERIPH_LPUART) ;
		LL_LPUART_SetBaudRate(m_t_UARTProfile[ui_DeviceID].usart, LL_LPUART_PRESCALER_DIV1, m_t_UARTProfile[ui_DeviceID].baudRate); 
		LL_LPUART_SetTransferDirection(m_t_UARTProfile[ui_DeviceID].usart, LL_LPUART_DIRECTION_TX_RX);
		LL_LPUART_ConfigCharacter(m_t_UARTProfile[ui_DeviceID].usart, LL_LPUART_DATAWIDTH_8B, LL_LPUART_PARITY_NONE, LL_LPUART_STOPBITS_1);
		LL_LPUART_Enable(m_t_UARTProfile[ui_DeviceID].usart);
		LL_LPUART_EnableIT_RXNE_RXFNE(m_t_UARTProfile[ui_DeviceID].usart);  
	}
	
	
	/* Enable the UART IRQ */
	NVIC_SetPriority(m_t_UARTProfile[ui_DeviceID].usart_irq, IRQ_HIGH_PRIORITY);
	NVIC_EnableIRQ(m_t_UARTProfile[ui_DeviceID].usart_irq);
	
	
	
}

void DrvUart_DeInit(uint ui_DeviceID)
{
//	uint8 u8_Port_TX = (m_t_UARTProfile[ui_DeviceID].ui_GPIOChannelTX & DRV_GPIO_MASK_PORT) >> 4;
//	uint8 u8_Pin_TX = m_t_UARTProfile[ui_DeviceID].ui_GPIOChannelTX & DRV_GPIO_MASK_PIN;
//	uint8 u8_Port_RX = (m_t_UARTProfile[ui_DeviceID].ui_GPIOChannelRX & DRV_GPIO_MASK_PORT) >> 4;
//	uint8 u8_Pin_RX = m_t_UARTProfile[ui_DeviceID].ui_GPIOChannelRX & DRV_GPIO_MASK_PIN;
//	
//	
//	/* Disable the UART interrupts */
//	LL_USART_DisableIT_RXNE(m_t_UARTProfile[ui_DeviceID].usart);
//	NVIC_DisableIRQ(m_t_UARTProfile[ui_DeviceID].usart_irq);
//	
//	/* Disable the UART peripheral */
//	LL_USART_Disable(m_t_UARTProfile[ui_DeviceID].usart);
//	
//	/* Disable the UART clock */
//	LL_APB1_DisableClock(LL_APB1_PERIPH_USART) ;
//	
//	/* Reset the UART pins */
//	LL_GPIO_SetPinMode(Port[u8_Port_RX], Pin[u8_Pin_RX], LL_GPIO_MODE_ANALOG);
//	LL_GPIO_SetPinSpeed(Port[u8_Port_RX], Pin[u8_Pin_RX], LL_GPIO_SPEED_FREQ_LOW);
//	LL_GPIO_SetPinOutputType(Port[u8_Port_RX], Pin[u8_Pin_RX], LL_GPIO_OUTPUT_OPENDRAIN);
//	LL_GPIO_SetPinPull(Port[u8_Port_RX], Pin[u8_Pin_RX], LL_GPIO_PULL_NO);
//	
//	LL_GPIO_SetPinMode(Port[u8_Port_TX], Pin[u8_Pin_TX], LL_GPIO_MODE_ANALOG);
//	LL_GPIO_SetPinSpeed(Port[u8_Port_TX], Pin[u8_Pin_TX], LL_GPIO_SPEED_FREQ_LOW);
//	LL_GPIO_SetPinOutputType(Port[u8_Port_TX], Pin[u8_Pin_TX], LL_GPIO_OUTPUT_OPENDRAIN);
//	LL_GPIO_SetPinPull(Port[u8_Port_TX], Pin[u8_Pin_TX], LL_GPIO_PULL_NO);
}



void DrvUart_SendByte
(
uint ui_DeviceID ,
uint8 u8_Byte
)
{
	/* Wait for TX FIFO not full flag to be raised */
	while (LL_USART_IsActiveFlag_TXE(m_t_UARTProfile[ui_DeviceID].usart) == 0);
	/* Send the byte to the UART */
	LL_USART_TransmitData8(m_t_UARTProfile[ui_DeviceID].usart, u8_Byte);
}
void DrvUart_WaitSendFinish(uint ui_DeviceID)
{
	while((LL_USART_IsActiveFlag_TXE_TXFNF(m_t_UARTProfile[ui_DeviceID].usart) == RESET) ||(LL_USART_IsActiveFlag_TC(m_t_UARTProfile[ui_DeviceID].usart) == RESET));
}

void DrvUart_SendData
(
uint ui_DeviceID ,
uint8 * u8p_Data,
uint16 u16_Len
)
{
	for (uint8 i = 0; i < u16_Len; i++) 
	{
		DrvUart_SendByte(ui_DeviceID ,u8p_Data[i]) ;
	}
}





int putchar(int c)
{	
	int value = EOF;
	/* put character to stdout */
	if (c != EOF) {
		uint8_t data = (uint8_t)c;
		DrvUart_SendByte(DRV_UART_DEVICE_ID_3 ,data) ;
		value = c;
	}
	return value;
}


//void  DrvUart_RX_Callback(void)
//{
//	uint8 	read_data ;
//	/* If the RX FIFO is Not Empty */
//	if(LL_USART_IsActiveFlag_RXNE(USART1) == 1)   
//	{
//		read_data = LL_USART_ReceiveData8(USART1);
//		LOG_INFO("read_data :%d\r\n", read_data);
//	}
//}






//Private function definition   私有函数定义

